using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.IMessage;
using HslCommunication.Core.Net;
using HslCommunication.Profinet.AllenBradley;

namespace HslCommunication.Profinet.Omron
{
	/// <summary>
	/// 基于连接的对象访问的CIP协议的实现
	/// </summary>
	public class OmronConnectedCipNet : NetworkDeviceBase
	{
		/// <inheritdoc cref="P:HslCommunication.Profinet.AllenBradley.AllenBradleyNet.SessionHandle" />
		public uint SessionHandle
		{
			get;
			protected set;
		}

		/// <inheritdoc cref="P:HslCommunication.Profinet.AllenBradley.AllenBradleyNet.Slot" />
		public byte Slot
		{
			get;
			set;
		} = 0;


		/// <summary>
		/// 实例化一个默认的对象
		/// </summary>
		public OmronConnectedCipNet()
		{
			base.WordLength = 2;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <summary>
		/// 根据指定的IP及端口来实例化这个连接对象
		/// </summary>
		/// <param name="ipAddress">PLC的Ip地址</param>
		/// <param name="port">PLC的端口号信息</param>
		public OmronConnectedCipNet(string ipAddress, int port = 44818)
		{
			IpAddress = ipAddress;
			Port = port;
			base.WordLength = 2;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <inheritdoc />
		protected override INetMessage GetNewNetMessage()
		{
			return new AllenBradleyMessage();
		}

		/// <inheritdoc />
		protected override OperateResult InitializationOnConnect(Socket socket)
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(socket, AllenBradleyHelper.RegisterSessionHandle());
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult operateResult2 = AllenBradleyHelper.CheckResponse(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			SessionHandle = base.ByteTransform.TransUInt32(operateResult.Content, 4);
			OperateResult<byte[]> operateResult3 = ReadFromCoreServer(socket, AllenBradleyHelper.PackCommandGetAttributesAll(new byte[2]
			{
				1,
				Slot
			}, SessionHandle));
			if (!operateResult3.IsSuccess)
			{
				return operateResult3;
			}
			OperateResult operateResult4 = AllenBradleyHelper.CheckResponse(operateResult3.Content);
			if (!operateResult4.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult4);
			}
			byte[] send = AllenBradleyHelper.PackRequestHeader(111, SessionHandle, "000000000000020000000000b20036005b022006240106ea020000800100fe8002001b0560e8a9050200000080841e00cc07004280841e00cc070042a3040100200224012c01".ToHexBytes());
			OperateResult<byte[]> operateResult5 = ReadFromCoreServer(socket, send);
			if (!operateResult5.IsSuccess)
			{
				return operateResult;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		protected override OperateResult ExtraOnDisconnect(Socket socket)
		{
			OperateResult<byte[]> operateResult = ReadFromCoreServer(socket, AllenBradleyHelper.UnRegisterSessionHandle(SessionHandle));
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		protected override async Task<OperateResult> InitializationOnConnectAsync(Socket socket)
		{
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(socket, AllenBradleyHelper.RegisterSessionHandle());
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = AllenBradleyHelper.CheckResponse(read.Content);
			if (!check.IsSuccess)
			{
				return check;
			}
			SessionHandle = base.ByteTransform.TransUInt32(read.Content, 4);
			OperateResult<byte[]> read2 = await ReadFromCoreServerAsync(socket, AllenBradleyHelper.PackCommandGetAttributesAll(new byte[2]
			{
				1,
				Slot
			}, SessionHandle));
			if (!read2.IsSuccess)
			{
				return read2;
			}
			OperateResult check2 = AllenBradleyHelper.CheckResponse(read2.Content);
			if (!check2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(check2);
			}
			byte[] send = AllenBradleyHelper.PackRequestHeader(111, SessionHandle, "000000000000020000000000b20036005b022006240106ea020000800100fe8002001b0560e8a9050200000080841e00cc07004280841e00cc070042a3040100200224012c01".ToHexBytes());
			OperateResult<byte[]> forward = await ReadFromCoreServerAsync(socket, send);
			if (!forward.IsSuccess)
			{
				return forward;
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		protected override async Task<OperateResult> ExtraOnDisconnectAsync(Socket socket)
		{
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(socket, AllenBradleyHelper.UnRegisterSessionHandle(SessionHandle));
			if (!read.IsSuccess)
			{
				return read;
			}
			return OperateResult.CreateSuccessResult();
		}

		private OperateResult<byte[]> BuildReadCommand(string address, int length)
		{
			try
			{
				byte[] commandSpecificData = AllenBradleyHelper.PackCommandSpecificData("a1 00 04 00 41 01 85 53".ToHexBytes(), PackCommandService(AllenBradleyHelper.PackRequsetRead(address, length, isConnectedAddress: true)));
				return OperateResult.CreateSuccessResult(AllenBradleyHelper.PackRequestHeader(112, SessionHandle, commandSpecificData));
			}
			catch (Exception ex)
			{
				return new OperateResult<byte[]>("Address Wrong:" + ex.Message);
			}
		}

		private OperateResult<byte[]> BuildWriteCommand(string address, ushort typeCode, byte[] data, int length = 1)
		{
			try
			{
				byte[] commandSpecificData = AllenBradleyHelper.PackCommandSpecificData("a1 00 04 00 41 01 85 53".ToHexBytes(), PackCommandService(AllenBradleyHelper.PackRequestWrite(address, typeCode, data, length, isConnectedAddress: true)));
				return OperateResult.CreateSuccessResult(AllenBradleyHelper.PackRequestHeader(112, SessionHandle, commandSpecificData));
			}
			catch (Exception ex)
			{
				return new OperateResult<byte[]>("Address Wrong:" + ex.Message);
			}
		}

		private byte[] PackCommandService(byte[] cip)
		{
			MemoryStream memoryStream = new MemoryStream();
			memoryStream.WriteByte(177);
			memoryStream.WriteByte(0);
			memoryStream.WriteByte(0);
			memoryStream.WriteByte(0);
			memoryStream.WriteByte(21);
			memoryStream.WriteByte(0);
			memoryStream.Write(cip, 0, cip.Length);
			byte[] array = memoryStream.ToArray();
			memoryStream.Dispose();
			BitConverter.GetBytes((short)(array.Length - 4)).CopyTo(array, 2);
			return array;
		}

		private OperateResult<byte[], ushort, bool> ReadWithType(string address, int length)
		{
			OperateResult<byte[]> operateResult = BuildReadCommand(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[], ushort, bool>(operateResult);
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[], ushort, bool>(operateResult2);
			}
			OperateResult operateResult3 = AllenBradleyHelper.CheckResponse(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[], ushort, bool>(operateResult3);
			}
			return ExtractActualData(operateResult2.Content, isRead: true);
		}

		private async Task<OperateResult<byte[], ushort, bool>> ReadWithTypeAsync(string address, int length)
		{
			OperateResult<byte[]> command = BuildReadCommand(address, length);
			if (!command.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[], ushort, bool>(command);
			}
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(command.Content);
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[], ushort, bool>(read);
			}
			OperateResult check = AllenBradleyHelper.CheckResponse(read.Content);
			if (!check.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[], ushort, bool>(check);
			}
			return ExtractActualData(read.Content, isRead: true);
		}

		/// <inheritdoc />
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<byte[], ushort, bool> operateResult = ReadWithType(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			return OperateResult.CreateSuccessResult(operateResult.Content1);
		}

		/// <inheritdoc />
		public override async Task<OperateResult<byte[]>> ReadAsync(string address, ushort length)
		{
			OperateResult<byte[], ushort, bool> read = await ReadWithTypeAsync(address, length);
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(read);
			}
			return OperateResult.CreateSuccessResult(read.Content1);
		}

		/// <summary>
		/// 当前的PLC不支持该功能，需要调用 <see cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.WriteTag(System.String,System.UInt16,System.Byte[],System.Int32)" /> 方法来实现。<br />
		/// The current PLC does not support this function, you need to call the <see cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.WriteTag(System.String,System.UInt16,System.Byte[],System.Int32)" /> method to achieve it.
		/// </summary>
		/// <param name="address">地址</param>
		/// <param name="value">值</param>
		/// <returns>写入结果值</returns>
		public override OperateResult Write(string address, byte[] value)
		{
			return new OperateResult(StringResources.Language.NotSupportedFunction + " Please refer to use WriteTag instead ");
		}

		/// <summary>
		/// 使用指定的类型写入指定的节点数据<br />
		/// Writes the specified node data with the specified type
		/// </summary>
		/// <param name="address">节点的名称 -&gt; Name of the node </param>
		/// <param name="typeCode">类型代码，详细参见<see cref="T:HslCommunication.Profinet.AllenBradley.AllenBradleyHelper" />上的常用字段 -&gt;  Type code, see the commonly used Fields section on the <see cref="T:HslCommunication.Profinet.AllenBradley.AllenBradleyHelper" /> in detail</param>
		/// <param name="value">实际的数据值 -&gt; The actual data value </param>
		/// <param name="length">如果节点是数组，就是数组长度 -&gt; If the node is an array, it is the array length </param>
		/// <returns>是否写入成功 -&gt; Whether to write successfully</returns>
		public virtual OperateResult WriteTag(string address, ushort typeCode, byte[] value, int length = 1)
		{
			OperateResult<byte[]> operateResult = BuildWriteCommand(address, typeCode, value, length);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult<byte[]> operateResult2 = ReadFromCoreServer(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			OperateResult operateResult3 = AllenBradleyHelper.CheckResponse(operateResult2.Content);
			if (!operateResult3.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult3);
			}
			return AllenBradleyHelper.ExtractActualData(operateResult2.Content, isRead: false);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Byte[])" />
		public override async Task<OperateResult> WriteAsync(string address, byte[] value)
		{
			return await Task.Run(() => Write(address, value));
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.WriteTag(System.String,System.UInt16,System.Byte[],System.Int32)" />
		public virtual async Task<OperateResult> WriteTagAsync(string address, ushort typeCode, byte[] value, int length = 1)
		{
			OperateResult<byte[]> command = BuildWriteCommand(address, typeCode, value, length);
			if (!command.IsSuccess)
			{
				return command;
			}
			OperateResult<byte[]> read = await ReadFromCoreServerAsync(command.Content);
			if (!read.IsSuccess)
			{
				return read;
			}
			OperateResult check = AllenBradleyHelper.CheckResponse(read.Content);
			if (!check.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(check);
			}
			return AllenBradleyHelper.ExtractActualData(read.Content, isRead: false);
		}

		/// <inheritdoc />
		public override OperateResult<short[]> ReadInt16(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransInt16(m, 0, length));
		}

		/// <inheritdoc />
		public override OperateResult<ushort[]> ReadUInt16(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransUInt16(m, 0, length));
		}

		/// <inheritdoc />
		public override OperateResult<int[]> ReadInt32(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransInt32(m, 0, length));
		}

		/// <inheritdoc />
		public override OperateResult<uint[]> ReadUInt32(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransUInt32(m, 0, length));
		}

		/// <inheritdoc />
		public override OperateResult<float[]> ReadFloat(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransSingle(m, 0, length));
		}

		/// <inheritdoc />
		public override OperateResult<long[]> ReadInt64(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransInt64(m, 0, length));
		}

		/// <inheritdoc />
		public override OperateResult<ulong[]> ReadUInt64(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransUInt64(m, 0, length));
		}

		/// <inheritdoc />
		public override OperateResult<double[]> ReadDouble(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(Read(address, length), (byte[] m) => base.ByteTransform.TransDouble(m, 0, length));
		}

		/// <inheritdoc />
		public OperateResult<string> ReadString(string address)
		{
			return ReadString(address, 1, Encoding.ASCII);
		}

		/// <inheritdoc />
		public override OperateResult<string> ReadString(string address, ushort length, Encoding encoding)
		{
			OperateResult<byte[]> operateResult = Read(address, length);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(operateResult);
			}
			if (operateResult.Content.Length >= 6)
			{
				int count = base.ByteTransform.TransInt32(operateResult.Content, 2);
				return OperateResult.CreateSuccessResult(encoding.GetString(operateResult.Content, 6, count));
			}
			return OperateResult.CreateSuccessResult(encoding.GetString(operateResult.Content));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<short[]>> ReadInt16Async(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransInt16(m, 0, length));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<ushort[]>> ReadUInt16Async(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransUInt16(m, 0, length));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<int[]>> ReadInt32Async(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransInt32(m, 0, length));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<uint[]>> ReadUInt32Async(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransUInt32(m, 0, length));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<float[]>> ReadFloatAsync(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransSingle(m, 0, length));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<long[]>> ReadInt64Async(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransInt64(m, 0, length));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<ulong[]>> ReadUInt64Async(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransUInt64(m, 0, length));
		}

		/// <inheritdoc />
		public override async Task<OperateResult<double[]>> ReadDoubleAsync(string address, ushort length)
		{
			return ByteTransformHelper.GetResultFromBytes(await ReadAsync(address, length), (byte[] m) => base.ByteTransform.TransDouble(m, 0, length));
		}

		/// <inheritdoc />
		public async Task<OperateResult<string>> ReadStringAsync(string address)
		{
			return await ReadStringAsync(address, 1, Encoding.ASCII);
		}

		/// <inheritdoc />
		public override async Task<OperateResult<string>> ReadStringAsync(string address, ushort length, Encoding encoding)
		{
			OperateResult<byte[]> read = await ReadAsync(address, length);
			if (!read.IsSuccess)
			{
				return OperateResult.CreateFailedResult<string>(read);
			}
			if (read.Content.Length >= 6)
			{
				return OperateResult.CreateSuccessResult(encoding.GetString(count: base.ByteTransform.TransInt32(read.Content, 2), bytes: read.Content, index: 6));
			}
			return OperateResult.CreateSuccessResult(encoding.GetString(read.Content));
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, short[] values)
		{
			return WriteTag(address, 195, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, ushort[] values)
		{
			return WriteTag(address, 195, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, int[] values)
		{
			return WriteTag(address, 196, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, uint[] values)
		{
			return WriteTag(address, 196, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, float[] values)
		{
			return WriteTag(address, 202, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, long[] values)
		{
			return WriteTag(address, 197, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, ulong[] values)
		{
			return WriteTag(address, 197, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, double[] values)
		{
			return WriteTag(address, 203, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				value = string.Empty;
			}
			byte[] bytes = Encoding.ASCII.GetBytes(value);
			OperateResult operateResult = Write(address + ".LEN", bytes.Length);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			byte[] value2 = SoftBasic.ArrayExpandToLengthEven(bytes);
			return WriteTag(address + ".DATA[0]", 194, value2, bytes.Length);
		}

		/// <inheritdoc />
		public override OperateResult Write(string address, bool value)
		{
			return WriteTag(address, 193, (!value) ? new byte[2] : new byte[2]
			{
				255,
				255
			});
		}

		/// <inheritdoc />
		public OperateResult Write(string address, byte value)
		{
			return WriteTag(address, 194, new byte[2]
			{
				value,
				0
			});
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Int16[])" />
		public override async Task<OperateResult> WriteAsync(string address, short[] values)
		{
			return await WriteTagAsync(address, 195, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.UInt16[])" />
		public override async Task<OperateResult> WriteAsync(string address, ushort[] values)
		{
			return await WriteTagAsync(address, 195, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Int32[])" />
		public override async Task<OperateResult> WriteAsync(string address, int[] values)
		{
			return await WriteTagAsync(address, 196, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.UInt32[])" />
		public override async Task<OperateResult> WriteAsync(string address, uint[] values)
		{
			return await WriteTagAsync(address, 196, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Single[])" />
		public override async Task<OperateResult> WriteAsync(string address, float[] values)
		{
			return await WriteTagAsync(address, 202, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Int64[])" />
		public override async Task<OperateResult> WriteAsync(string address, long[] values)
		{
			return await WriteTagAsync(address, 197, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.UInt64[])" />
		public override async Task<OperateResult> WriteAsync(string address, ulong[] values)
		{
			return await WriteTagAsync(address, 197, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Double[])" />
		public override async Task<OperateResult> WriteAsync(string address, double[] values)
		{
			return await WriteTagAsync(address, 203, base.ByteTransform.TransByte(values), values.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.String)" />
		public override async Task<OperateResult> WriteAsync(string address, string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				value = string.Empty;
			}
			byte[] data = Encoding.ASCII.GetBytes(value);
			OperateResult write = await WriteAsync(address + ".LEN", data.Length);
			if (!write.IsSuccess)
			{
				return write;
			}
			return await WriteTagAsync(value: SoftBasic.ArrayExpandToLengthEven(data), address: address + ".DATA[0]", typeCode: 194, length: data.Length);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Boolean)" />
		public override async Task<OperateResult> WriteAsync(string address, bool value)
		{
			return await WriteTagAsync(address, 193, (!value) ? new byte[2] : new byte[2]
			{
				255,
				255
			});
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.Omron.OmronConnectedCipNet.Write(System.String,System.Byte)" />
		public async Task<OperateResult> WriteAsync(string address, byte value)
		{
			return await WriteTagAsync(address, 194, new byte[2]
			{
				value,
				0
			});
		}

		/// <summary>
		/// 从PLC反馈的数据解析
		/// </summary>
		/// <param name="response">PLC的反馈数据</param>
		/// <param name="isRead">是否是返回的操作</param>
		/// <returns>带有结果标识的最终数据</returns>
		public static OperateResult<byte[], ushort, bool> ExtractActualData(byte[] response, bool isRead)
		{
			List<byte> list = new List<byte>();
			int num = 42;
			bool value = false;
			ushort value2 = 0;
			ushort num2 = BitConverter.ToUInt16(response, num);
			byte b = response[num + 6];
			switch (b)
			{
			case 4:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.AllenBradley04
				};
			case 5:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.AllenBradley05
				};
			case 6:
				value = true;
				break;
			case 10:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.AllenBradley0A
				};
			case 19:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.AllenBradley13
				};
			case 28:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.AllenBradley1C
				};
			case 30:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.AllenBradley1E
				};
			case 38:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.AllenBradley26
				};
			default:
				return new OperateResult<byte[], ushort, bool>
				{
					ErrorCode = b,
					Message = StringResources.Language.UnknownError
				};
			case 0:
				break;
			}
			if (response[num + 4] == 205 || response[num + 4] == 211)
			{
				return OperateResult.CreateSuccessResult(list.ToArray(), value2, value);
			}
			if (response[num + 4] == 204 || response[num + 4] == 210)
			{
				for (int i = num + 10; i < num + 2 + num2; i++)
				{
					list.Add(response[i]);
				}
				value2 = BitConverter.ToUInt16(response, num + 8);
			}
			else if (response[num + 4] == 213)
			{
				for (int j = num + 8; j < num + 2 + num2; j++)
				{
					list.Add(response[j]);
				}
			}
			return OperateResult.CreateSuccessResult(list.ToArray(), value2, value);
		}
	}
}
